exoskeleton.mixins.required_elements = {
  add_required_element: function(element){
    if(!this.required_elements){
      this.required_elements = []
    }
    if(_.isUndefined(this.required_element_error_shown)){
      this.required_element_error_shown = false
    }
    var _this = this;
    element.bind('fetch:complete', function(event_element){
      // Prevent triggering render on sub-models and sub-collections.
      if( event_element === element ){
        _this.render();
      }
    }, this);
    this.required_elements.push(element)
  },
  required_elements_loaded: function(){
    if(!this.required_elements){
      this.required_elements = []
    }
    var loaded = true
    var successful = true
    var system_error = false

    for(var i=0; i<this.required_elements.length; i++){
      var element = this.required_elements[i]
      if(!(element.fetchStatus().is_complete)){
        loaded = false
        break;
      }
      if(!(element.fetchStatus().successful())){
        successful = false
        if(element.fetchStatus().system_error()){
          system_error = true
        }
        break;
      }
    }

    var status = {
      loaded: loaded,
      successful: successful,
      system_error: system_error
    }

    return status
  },
  render: function(){
    if(this.required_element_error_shown){
       return this
    }
    var load_status = this.required_elements_loaded()
    if(!load_status.loaded){
     this.render_progress()
     return this
    }

    if(!load_status.successful){
     if(load_status.system_error){
       this.system_error()
       return this
     }
     this.required_element_error_shown = true
     this.render_error()
     return this
    }

    this.render_successful()
    return this
  },
  system_error: function(){
    //Blank method incase it is not implemented on older views
  },
  render_error: function(){
    //Blank method incase it is not implemented on older views
  }


}
